package io.itit.ecp.admin.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import io.itit.ecp.admin.server.entity.DataFillingDataEntity;
import io.itit.ecp.admin.server.entity.DataFillingDetailEntity;
import io.itit.ecp.admin.server.entity.DataFillingEntity;
import io.itit.ecp.admin.server.mapper.DataFillingDetailMapper;
import io.itit.ecp.admin.server.mapper.DataFillingMapper;
import io.itit.ecp.admin.server.service.IDataFillingDataService;
import io.itit.ecp.admin.server.service.IDataFillingService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


@Service
@RequiredArgsConstructor
public class DataFillingServiceImpl extends JoinServiceImpl<DataFillingMapper, DataFillingEntity>
        implements IDataFillingService {

    private final DataFillingDetailMapper dataFillingDetailMapper;

    private final IDataFillingDataService dataFillingDataService;

    @Override
    @Transactional
    public Boolean saveOrUpdateDetail(DataFillingEntity dataFillingEntity, String detailJson) {
        if (StringUtils.hasLength(dataFillingEntity.getId())) {
            dataFillingDetailMapper.delete(new LambdaQueryWrapper<DataFillingDetailEntity>()
                    .eq(DataFillingDetailEntity::getDataFillingId, dataFillingEntity.getId()));
            dataFillingDataService.deleteByDataFillingId(dataFillingEntity.getId());
        }
        boolean result = this.saveOrUpdate(dataFillingEntity);
        List<DataFillingDetailEntity> detailEntities = JSON.parseArray(detailJson, DataFillingDetailEntity.class);
        if (!CollectionUtils.isEmpty(detailEntities)) {
            for (DataFillingDetailEntity item : detailEntities) {
                item.setDataFillingId(dataFillingEntity.getId());
                dataFillingDetailMapper.insert(item);
            }
        }
        List<DataFillingDataEntity> fillingDataEntities = getDataFillingDataEntities(dataFillingEntity, detailEntities);
        dataFillingDataService.saveBatch(fillingDataEntities);
        return result;
    }

    private static List<DataFillingDataEntity> getDataFillingDataEntities(DataFillingEntity dataFillingEntity, List<DataFillingDetailEntity> detailEntities) {
        LocalDateTime end = dataFillingEntity.getDataEndTime().atTime(LocalTime.MAX);
        LocalDateTime item = dataFillingEntity.getDataStartTime().atTime(LocalTime.MIN);
        BigDecimal hours = new BigDecimal(ChronoUnit.HOURS.between(item, end));
        List<DataFillingDataEntity> fillingDataEntities = new ArrayList<>();
        do {
            for (DataFillingDetailEntity dataFillingDetail : detailEntities) {
                DataFillingDataEntity entity = new DataFillingDataEntity();
                entity.setDataFillingId(dataFillingEntity.getId());
                entity.setActivityCarbonEmissionId(dataFillingEntity.getActivityCarbonEmissionId());
                entity.setSolidifyDate(item);
                entity.setSceneProjectId(dataFillingEntity.getSceneProjectId());
                entity.setSceneEdificeId(dataFillingEntity.getSceneEdificeId());
                entity.setSceneFloorId(dataFillingEntity.getSceneFloorId());
                entity.setSceneRoomId(dataFillingEntity.getSceneRoomId());
                entity.setEnergyConsumptionTypeId(dataFillingDetail.getEnergyConsumptionTypeId());
                entity.setCarbonEmission(dataFillingDetail.getCarbonEmission().divide(hours, RoundingMode.HALF_DOWN));
                fillingDataEntities.add(entity);
            }
            item = item.plusHours(1);
        } while (item.isBefore(end) || item.isEqual(end));
        return fillingDataEntities;
    }

    @Override
    public List<DataFillingEntity> selectByActivityCarbonId(String activityCarbonEmissionId) {
        return list(new LambdaQueryWrapper<DataFillingEntity>()
                .eq(DataFillingEntity::getActivityCarbonEmissionId, activityCarbonEmissionId));
    }

    @Override
    @Transactional
    public Boolean removeByDataFillingDataId(String id) {
        DataFillingDataEntity fillingDataEntity = dataFillingDataService.getById(id);
        if (Objects.nonNull(fillingDataEntity)) {
            dataFillingDataService.removeById(id);
            if (dataFillingDataService.countByDataFillingId(id) == 0L) {
                dataFillingDetailMapper.delete(new LambdaQueryWrapper<DataFillingDetailEntity>()
                        .eq(DataFillingDetailEntity::getDataFillingId, fillingDataEntity.getId()));
                removeById(id);
            }
        }
        return true;
    }
}
